
#include "csvProcessApi.h"
#include "curl.h"
#include "easy.h"
#include "logger.h"
#include <iostream>
#include <assert.h>
#include <filesystem>  // C++17 或更高版本
#include <chrono>
#include <thread>
#include "ThreadPool.h"

namespace fs = std::filesystem;

fs::path getDataDir()
{
    // 当前工作目录
    fs::path cwd = fs::current_path();

    // 1. 当前目录下的 data/
    fs::path releaseData = cwd;
    if (fs::exists(releaseData) && fs::is_directory(releaseData)) {
        return releaseData;
    }

    // 2. 工程根目录下的 data/
    fs::path devData = cwd / ".." / "..";
    devData = fs::weakly_canonical(devData);
    if (fs::exists(devData) && fs::is_directory(devData)) {
        return devData;
    }

    // 都不存在，返回空路径
    return fs::path();
}

std::shared_ptr<spdlog::logger> logger = CreateFileLoggerWithTimestamp();
std::string getDataPath();
void TestStreaming();
void TestCSV() ;
bool FtpDownload(const std::string& ftpUrl,
                 const std::string& localFile,
                 const std::string& username,
                 const std::string& password);
bool FtpUpload(const std::string& ftpUrl,
               const std::string& localFile,
               const std::string& username,
               const std::string& password);

void TestConnectToFTP();
void InitCurlGlobal();

// constexpr int f() noexcept { return 0; }
int main() 
{
    fs::path dataDir = getDataDir();

    if (dataDir.empty()) {
        std::cerr << "Data directory not found!" << std::endl;
        return 1;
    }

    fs::path inputFile = dataDir / "data/taifang_raw_data.bin";

    // static_assert(noexcept(f()), "f should be noexcept");
    // 测试 CSV 转 BIN 和 BIN 转 CSV
    // TestCSV();

    /**************************************************************************/

    std::string inputtBin2 = dataDir.u8string() + "/data/taifang_raw_data.bin";
    //  std::string inputtBin2 = dataDir.u8string() + "/output_data1.bin";
    std::cout << "inputtBin2: " << inputtBin2 << std::endl;
    // std::string inputtBin2 = "./data/taifang_raw_data.bin";    // 输入 Bin 文件
    // std::string inputtBin2 = "./data/output_data100M.bin";
    std::string outputCSV2 = "./data/output.csv";    // 最终输出的 CSV 文件
    time_t now = time(nullptr);
    auto m_start = std::chrono::high_resolution_clock::now();
    binToCsvStreaming(inputtBin2, outputCSV2, true); // 调用转换函数
    auto end = std::chrono::high_resolution_clock::now();
    std::cout << "All Time used: " <<std::dec<< std::chrono::duration_cast<std::chrono::milliseconds>(end - m_start).count() << " MS" << std::endl;
    std::cout << "binToCsvStreaming Done\n";
    std::cout.flush();
    /************************************************************************/
    
    return 0;
}
 

void InitCurlGlobal()
{
    static bool initialized = false;
    if (!initialized) {
        curl_global_init(CURL_GLOBAL_DEFAULT);
        initialized = true;
    }
}

bool FtpUpload(const std::string& ftpUrl,
               const std::string& localFile,
               const std::string& username,
               const std::string& password)
{
    InitCurlGlobal();

    CURL* curl = curl_easy_init();
    if (!curl) return false;

    FILE* file = fopen(localFile.c_str(), "rb");
    if (!file) {
        curl_easy_cleanup(curl);
        return false;
    }

    std::string fullUrl = ftpUrl;  // e.g., "ftp://127.0.0.1/upload/filename.txt"

    curl_easy_setopt(curl, CURLOPT_URL, fullUrl.c_str());
    curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
    curl_easy_setopt(curl, CURLOPT_READDATA, file);

    std::string userpwd = username + ":" + password;
    curl_easy_setopt(curl, CURLOPT_USERPWD, userpwd.c_str());

    CURLcode res = curl_easy_perform(curl);

    fclose(file);
    curl_easy_cleanup(curl);

    return (res == CURLE_OK);
}

bool FtpDownload(const std::string& ftpUrl,
                 const std::string& localFile,
                 const std::string& username,
                 const std::string& password)
{
    InitCurlGlobal();

    CURL* curl = curl_easy_init();
    if (!curl) return false;

    FILE* file = fopen(localFile.c_str(), "wb");
    if (!file) {
        curl_easy_cleanup(curl);
        return false;
    }

    std::string userpwd = username + ":" + password;

    curl_easy_setopt(curl, CURLOPT_URL, ftpUrl.c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, nullptr);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
    curl_easy_setopt(curl, CURLOPT_USERPWD, userpwd.c_str());

    CURLcode res = curl_easy_perform(curl);

    fclose(file);
    curl_easy_cleanup(curl);

    return (res == CURLE_OK);
}

void TestConnectToFTP()
{
    std::string ftpServer = "ftp://10.10.10.10";
    std::string ftpUser = "admin";
    std::string ftpPassword = "admin";
    std::string ftpPath = "/data/00001_20240910_070702_861_00000_0167_4_1.csv";
}

void TestStreaming() 
{
    std::string csvPath = "data/00001_20240910_070702_861_00000_0167_4_1.csv";
    const std::string binPath = "data/output_streaming.bin";

    // 流式 CSV 转 BIN
    csvToBinStreaming(csvPath, binPath);


    // 流式 BIN 转 CSV
    std::string csvOutputPath = "data/output_streaming.csv";
    binToCsvStreaming(binPath, csvOutputPath, true);
    
}


void TestCSV() 
{
    std::string csvInput = "data/origin.csv";
    std::string binOutput = "data/output.bin";
    std::string binInput = "data/output.bin";
    std::string csvOutput = "data/output_converted.csv";

    // CSV 转 BIN
    csvToBin(csvInput, binOutput);
    LOG_INFO("csvToBin Done 12346");

    // BIN 转 CSV
    binToCsv(binInput, csvOutput);
    LOG_INFO("binToCsv Done");
}